
import { _decorator, Component, Node, Sprite, UITransform, Animation, animation, AnimationClip, Vec3, SpriteFrame } from 'cc'
import { TILE_HEIGHT, TILE_WIDTH } from '../Tile/TileManager'
import ResourceManager from '../../Runtime/ResourceManager'
import { CONTROLLER_ENUM, EVENT_ENUM, PARAMS_NAME_ENUM, DIRECTION_ENUM, ENTITY_STATE_ENUM, DIRECTION_ORDER_ENUM, ENTITY_TYPE_ENUM, SHAKE_TYPE_ENUM } from '../../Enums'
import EventManager from '../../Runtime/EventManager'
import { PlayerStateMachine } from './PlayerStateMachine'
import { EntityManager } from '../../Base/EntityManager'
import DataManager from '../../Runtime/DataManager'
import { IEntity } from '../../Levels'
import { EnemyManager } from '../../Base/EnemyManager'
import { BurstManager } from '../Burst/BurstManager'
const { ccclass, property } = _decorator

@ccclass('PlayerManager')
export class PlayerManager extends EntityManager {
    targetX: number = 0
    targetY: number = 0
    isMoving: boolean = false
    private readonly speed = 1 / 10

    async init(params: IEntity) {
        this.fsm = this.addComponent(PlayerStateMachine)
        await this.fsm.init()
        super.init(params)

        this.targetX = this.x
        this.targetY = this.y

        EventManager.Instance.on(EVENT_ENUM.PLAYER_CTRL, this.inputHandle, this)
        EventManager.Instance.on(EVENT_ENUM.ATTACK_PLAYER, this.onDead, this)
    }

    onDestroy() {
        super.onDestroy()
        EventManager.Instance.off(EVENT_ENUM.PLAYER_CTRL, this.inputHandle)
        EventManager.Instance.off(EVENT_ENUM.ATTACK_PLAYER, this.onDead)
    }

    update() {
        this.updateXY()
        // this.node.setPosition(this.x * TILE_WIDTH - TILE_WIDTH * 1.5, -this.y * TILE_HEIGHT + TILE_HEIGHT * 1.5)
        super.update()
    }

    updateXY() {
        if (this.targetX < this.x) {
            this.x -= this.speed
        } else if (this.targetX > this.x) {
            this.x += this.speed
        }

        if (this.targetY < this.y) {
            this.y -= this.speed
        } else if (this.targetY > this.y) {
            this.y += this.speed
        }

        if (Math.abs(this.targetX - this.x) <= 0.1 && Math.abs(this.targetY - this.y) <= 0.1 && this.isMoving) {
            this.isMoving = false
            this.x = this.targetX
            this.y = this.targetY
            EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
        }
    }

    onDead(type: ENTITY_STATE_ENUM) {
        this.state = type
    }

    onAttackShake(type: SHAKE_TYPE_ENUM) {
        EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, type)
    }

    inputHandle(inputDirection: CONTROLLER_ENUM) {
        if (this.isMoving) {
            return
        }

        // 如果当前状态是死亡状态或者正在攻击，则不处理输入
        if (this.state === ENTITY_STATE_ENUM.DEATH || this.state === ENTITY_STATE_ENUM.AIR_DEATH || this.state === ENTITY_STATE_ENUM.ATTACK) {
            return
        }

        // 判断能否攻击到敌人
        const enemyId = this.willAttack(inputDirection)
        if (enemyId) {
            EventManager.Instance.emit(EVENT_ENUM.RECORD_STEP)
            this.state = ENTITY_STATE_ENUM.ATTACK
            EventManager.Instance.emit(EVENT_ENUM.ATTACK_ENEMY, enemyId)
            // 这里立即触发开门事件其实不太合适，因为敌人死亡动画都还没有结束
            EventManager.Instance.emit(EVENT_ENUM.DOOR_OPEN)
            EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
            return
        }

        if (this.willBlock(inputDirection)) {
            // 碰撞的时候触发震动事件
            if (inputDirection === CONTROLLER_ENUM.TOP) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.TOP)
            } else if (inputDirection === CONTROLLER_ENUM.BOTTOM) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.BOTTOM)
            } else if (inputDirection === CONTROLLER_ENUM.LEFT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.LEFT)
            } else if (inputDirection === CONTROLLER_ENUM.RIGHT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.RIGHT)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_LEFT && this.direction === DIRECTION_ENUM.TOP) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.LEFT)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_LEFT && this.direction === DIRECTION_ENUM.LEFT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.BOTTOM)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_LEFT && this.direction === DIRECTION_ENUM.BOTTOM) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.RIGHT)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_LEFT && this.direction === DIRECTION_ENUM.RIGHT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.TOP)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_RIGHT && this.direction === DIRECTION_ENUM.TOP) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.RIGHT)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_RIGHT && this.direction === DIRECTION_ENUM.LEFT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.TOP)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_RIGHT && this.direction === DIRECTION_ENUM.BOTTOM) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.LEFT)
            } else if (inputDirection === CONTROLLER_ENUM.TURN_RIGHT && this.direction === DIRECTION_ENUM.RIGHT) {
                EventManager.Instance.emit(EVENT_ENUM.SCREEN_SHAKE, SHAKE_TYPE_ENUM.BOTTOM)
            }
            return
        }

        this.move(inputDirection)
    }

    move(inputDirection: CONTROLLER_ENUM) {
        EventManager.Instance.emit(EVENT_ENUM.RECORD_STEP)
        console.log('PlayerManager move:', inputDirection)
        switch (inputDirection) {
            case CONTROLLER_ENUM.TOP:
                this.targetY -= 1
                this.isMoving = true
                this.showSmoke(DIRECTION_ENUM.TOP)
                break
            case CONTROLLER_ENUM.BOTTOM:
                this.targetY += 1
                this.isMoving = true
                this.showSmoke(DIRECTION_ENUM.BOTTOM)
                break
            case CONTROLLER_ENUM.LEFT:
                this.targetX -= 1
                this.isMoving = true
                this.showSmoke(DIRECTION_ENUM.LEFT)
                break
            case CONTROLLER_ENUM.RIGHT:
                this.targetX += 1
                this.isMoving = true
                this.showSmoke(DIRECTION_ENUM.LEFT)
                break
            case CONTROLLER_ENUM.TURN_LEFT:
                // 左转，当根据当前的方向进行转向
                if (this.direction === DIRECTION_ENUM.TOP) {
                    this.direction = DIRECTION_ENUM.LEFT
                } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
                    this.direction = DIRECTION_ENUM.RIGHT
                } else if (this.direction === DIRECTION_ENUM.LEFT) {
                    this.direction = DIRECTION_ENUM.BOTTOM
                } else if (this.direction === DIRECTION_ENUM.RIGHT) {
                    this.direction = DIRECTION_ENUM.TOP
                }
                this.state = ENTITY_STATE_ENUM.TURN_LEFT
                EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
                break
            case CONTROLLER_ENUM.TURN_RIGHT:
                // 右转，当根据当前的方向进行转向
                if (this.direction === DIRECTION_ENUM.TOP) {
                    this.direction = DIRECTION_ENUM.RIGHT
                } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
                    this.direction = DIRECTION_ENUM.LEFT
                } else if (this.direction === DIRECTION_ENUM.LEFT) {
                    this.direction = DIRECTION_ENUM.TOP
                } else if (this.direction === DIRECTION_ENUM.RIGHT) {
                    this.direction = DIRECTION_ENUM.BOTTOM
                }
                this.state = ENTITY_STATE_ENUM.TURN_RIGHT
                EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
                break
        }
    }

    showSmoke(type: DIRECTION_ENUM) {
        EventManager.Instance.emit(EVENT_ENUM.SHOW_SMOKE, this.x, this.y, type)
    }

    willAttack(inputDirection: CONTROLLER_ENUM) {
        const enemies = DataManager.Instance.enemies.filter(enemy => enemy.state !== ENTITY_STATE_ENUM.DEATH)
        for (let i = 0; i < enemies.length; i++) {
            const { x: enemyX, y: enemyY, id: enemyId } = enemies[i]
            if (
                inputDirection === CONTROLLER_ENUM.TOP &&
                this.direction === DIRECTION_ENUM.TOP &&
                enemyX === this.x &&
                enemyY === this.targetY - 2
            ) {
                // this.state = ENTITY_STATE_ENUM.ATTACK
                return enemyId
            } else if (
                inputDirection === CONTROLLER_ENUM.LEFT &&
                this.direction === DIRECTION_ENUM.LEFT &&
                enemyX === this.x - 2 &&
                enemyY === this.targetY
            ) {
                // this.state = ENTITY_STATE_ENUM.ATTACK
                return enemyId
            } else if (
                inputDirection === CONTROLLER_ENUM.BOTTOM &&
                this.direction === DIRECTION_ENUM.BOTTOM &&
                enemyX === this.x &&
                enemyY === this.targetY + 2
            ) {
                // this.state = ENTITY_STATE_ENUM.ATTACK
                return enemyId
            } else if (
                inputDirection === CONTROLLER_ENUM.RIGHT &&
                this.direction === DIRECTION_ENUM.RIGHT &&
                enemyX === this.x + 2 &&
                enemyY === this.targetY
            ) {
                // this.state = ENTITY_STATE_ENUM.ATTACK
                return enemyId
            }
        }

        return ''
    }

    willBlock(type: CONTROLLER_ENUM) {
        const { targetX: x, targetY: y, direction } = this
        const { tileInfo } = DataManager.Instance

        const { x: doorX, y: doorY, state: doorState } = DataManager.Instance.door || {}
        const enemies: EnemyManager[] = DataManager.Instance.enemies.filter(
            (enemy: EnemyManager) => enemy.state !== ENTITY_STATE_ENUM.DEATH,
        )
        // 地裂，即使不存在tile地砖，有地裂也可以行走
        const bursts: BurstManager[] = DataManager.Instance.bursts.filter(
            (burst: BurstManager) => burst.state !== ENTITY_STATE_ENUM.DEATH,
        )

        const { mapRowCount, mapColumnCount } = DataManager.Instance

        //按钮方向——向上
        if (type === CONTROLLER_ENUM.TOP) {
            const playerNextY = y - 1

            //玩家方向——向上
            if (direction === DIRECTION_ENUM.TOP) {
                //判断是否超出地图
                if (playerNextY < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                const weaponNextY = y - 2
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[x]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                // 判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === weaponNextY) || (enemyX === x && enemyY === playerNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                //玩家方向——向下
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                //判断是否超出地图
                if (playerNextY < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                const weaponNextY = y
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[x]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if (enemyX === x && enemyY === playerNextY) {
                        this.state = ENTITY_STATE_ENUM.BLOCKBACK
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //玩家方向——向左
            } else if (direction === DIRECTION_ENUM.LEFT) {
                //判断是否超出地图
                if (playerNextY < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                const weaponNextX = x - 1
                const weaponNextY = y - 1
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //玩家方向——向右
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                //判断是否超出地图
                if (playerNextY < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                const weaponNextX = x + 1
                const weaponNextY = y - 1
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                        return true
                    }
                }

                // 判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }
            }

            //按钮方向——向下
        } else if (type === CONTROLLER_ENUM.BOTTOM) {
            const playerNextY = y + 1

            //玩家方向——向上
            if (direction === DIRECTION_ENUM.TOP) {
                if (playerNextY > mapColumnCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK

                    return true
                }

                const weaponNextY = y
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[x]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if (enemyX === x && enemyY === playerNextY) {
                        this.state = ENTITY_STATE_ENUM.BLOCKBACK
                        return true
                    }
                }

                // 判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //玩家方向——向下
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                if (playerNextY > mapColumnCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT

                    return true
                }

                const weaponNextY = y + 2
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[x]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                // 判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === weaponNextY) || (enemyX === x && enemyY === playerNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                //玩家方向——向左
            } else if (direction === DIRECTION_ENUM.LEFT) {
                if (playerNextY > mapColumnCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT

                    return true
                }

                const weaponNextX = x - 1
                const weaponNextY = y + 1
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //玩家方向——向右
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                if (playerNextY > mapColumnCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT

                    return true
                }

                const weaponNextX = x + 1
                const weaponNextY = y + 1
                const nextPlayerTile = tileInfo[x]?.[playerNextY]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }
            }

            //按钮方向——向左
        } else if (type === CONTROLLER_ENUM.LEFT) {
            const playerNextX = x - 1

            //玩家方向——向上
            if (direction === DIRECTION_ENUM.TOP) {
                //判断是否超出地图
                if (playerNextX < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT

                    return true
                }

                const weaponNextX = x - 1
                const weaponNextY = y - 1
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //玩家方向——向下
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                //判断是否超出地图
                if (playerNextX < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT

                    return true
                }

                const weaponNextX = x - 1
                const weaponNextY = y + 1
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //玩家方向——向左
            } else if (direction === DIRECTION_ENUM.LEFT) {
                //判断是否超出地图
                if (playerNextX < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT

                    return true
                }

                const weaponNextX = x - 2
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[y]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === y)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                //玩家方向——向右
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                //判断是否超出地图
                if (playerNextX < 0) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK

                    return true
                }

                const weaponNextX = x
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[y]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if (enemyX === playerNextX && enemyY === y) {
                        this.state = ENTITY_STATE_ENUM.BLOCKBACK
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }
            }

            //按钮方向——向右
        } else if (type === CONTROLLER_ENUM.RIGHT) {
            const playerNextX = x + 1

            //玩家方向——向上
            if (direction === DIRECTION_ENUM.TOP) {
                if (playerNextX > mapRowCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT

                    return true
                }

                const weaponNextX = x + 1
                const weaponNextY = y - 1
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
                    return true
                }

                //玩家方向——向下
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                if (playerNextX > mapRowCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT

                    return true
                }

                const weaponNextX = x + 1
                const weaponNextY = y + 1
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[weaponNextY]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKLEFT
                    return true
                }

                //玩家方向——向左
            } else if (direction === DIRECTION_ENUM.LEFT) {
                if (playerNextX > mapRowCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK

                    return true
                }

                const weaponNextX = x
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[y]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if (enemyX === playerNextX && enemyY === y) {
                        this.state = ENTITY_STATE_ENUM.BLOCKBACK
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKBACK
                    return true
                }

                //玩家方向——向右
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                if (playerNextX > mapRowCount - 1) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT

                    return true
                }

                const weaponNextX = x + 2
                const nextPlayerTile = tileInfo[playerNextX]?.[y]
                const nextWeaponTile = tileInfo[weaponNextX]?.[y]

                //判断门
                if (
                    ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
                    doorState !== ENTITY_STATE_ENUM.DEATH
                ) {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }

                //判断敌人
                for (let i = 0; i < enemies.length; i++) {
                    const enemy = enemies[i]
                    const { x: enemyX, y: enemyY } = enemy

                    if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === y)) {
                        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                        return true
                    }
                }

                //判断地裂陷阱
                if (
                    bursts.some(burst => burst.x === playerNextX && burst.y === y) &&
                    (!nextWeaponTile || nextWeaponTile.turnable)
                ) {
                    return false
                }

                //最后判断地图元素
                if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
                    // empty
                } else {
                    this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                    return true
                }
            }

            //按钮方向——左转
        } else if (type === CONTROLLER_ENUM.TURN_LEFT) {
            let nextY, nextX
            if (direction === DIRECTION_ENUM.TOP) {
                //朝上左转的话，左上角三个tile都必须turnable为true，并且没有敌人
                nextY = y - 1
                nextX = x - 1
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                nextY = y + 1
                nextX = x + 1
            } else if (direction === DIRECTION_ENUM.LEFT) {
                nextY = y + 1
                nextX = x - 1
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                nextY = y - 1
                nextX = x + 1
            }

            //判断门
            if (
                ((doorX === x && doorY === nextY) ||
                    (doorX === nextX && doorY === y) ||
                    (doorX === nextX && doorY === nextY)) &&
                doorState !== ENTITY_STATE_ENUM.DEATH
            ) {
                this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
                return true
            }

            //判断敌人
            for (let i = 0; i < enemies.length; i++) {
                const enemy = enemies[i]
                const { x: enemyX, y: enemyY } = enemy

                if (enemyX === nextX && enemyY === y) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT

                    return true
                } else if (enemyX === nextX && enemyY === nextY) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT

                    return true
                } else if (enemyX === x && enemyY === nextY) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT

                    return true
                }
            }

            //最后判断地图元素
            if (
                (!tileInfo[x]?.[nextY] || tileInfo[x]?.[nextY].turnable) &&
                (!tileInfo[nextX]?.[y] || tileInfo[nextX]?.[y].turnable) &&
                (!tileInfo[nextX]?.[nextY] || tileInfo[nextX]?.[nextY].turnable)
            ) {
                // empty
            } else {
                this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
                return true
            }

            //按钮方向——右转
        } else if (type === CONTROLLER_ENUM.TURN_RIGHT) {
            let nextX, nextY
            if (direction === DIRECTION_ENUM.TOP) {
                //朝上右转的话，右上角三个tile都必须turnable为true
                nextY = y - 1
                nextX = x + 1
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                nextY = y + 1
                nextX = x - 1
            } else if (direction === DIRECTION_ENUM.LEFT) {
                nextY = y - 1
                nextX = x - 1
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                nextY = y + 1
                nextX = x + 1
            }

            //判断门
            if (
                ((doorX === x && doorY === nextY) ||
                    (doorX === nextX && doorY === y) ||
                    (doorX === nextX && doorY === nextY)) &&
                doorState !== ENTITY_STATE_ENUM.DEATH
            ) {
                this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
                return true
            }

            //判断敌人
            for (let i = 0; i < enemies.length; i++) {
                const enemy = enemies[i]
                const { x: enemyX, y: enemyY } = enemy

                if (enemyX === nextX && enemyY === y) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT

                    return true
                } else if (enemyX === nextX && enemyY === nextY) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT

                    return true
                } else if (enemyX === x && enemyY === nextY) {
                    this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT

                    return true
                }
            }

            //最后判断地图元素
            if (
                (!tileInfo[x]?.[nextY] || tileInfo[x]?.[nextY].turnable) &&
                (!tileInfo[nextX]?.[y] || tileInfo[nextX]?.[y].turnable) &&
                (!tileInfo[nextX]?.[nextY] || tileInfo[nextX]?.[nextY].turnable)
            ) {
                // empty
            } else {
                this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
                return true
            }
        }

        return false
    }


}
